/**
 * ArffGenerate.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package plagio.utils;

import java.text.DecimalFormat;
import weka.core.Attribute;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.FastVector;
import java.util.ArrayList;

/**
 * This class is responsable by generate files ARFF for comparation.
 * @author Jose Mauro da Silva Sandy
 * @version Beta
 */
public class ArffGenerate {
    private String fileStemmer = "";

    /**
     * @return the text
     */
    public String getText() {
        return fileStemmer;
    }

    /**
     * @param text the text to set
     */
    public void setText(String fileStemmer) {
        this.fileStemmer = fileStemmer;
    }

    /**
     * @see Constructor Default
     */
    public ArffGenerate(){
    }
    /**
     * @param lines: receives the lines that will be processed on .ARFF.
     * @param relationName: the name of relation created by file .ARFF.
     * @param type of file .ARFF. 1 - PHRASE or 2 -WORD
     * @return a new file processed on .ARFF.
     */
    public StringBuilder fileArffString(String[] lines, String relationName,
            int type){
        StringBuilder writer = new StringBuilder();
        try{
            // Verifier the type of creation.
            switch(type){
                case 1:writer.append(fileArffPhrase(lines, relationName));break;
                case 2: writer.append(fileArffWord(lines, relationName)); break;
                default: writer = null; break;
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
            writer = null;
        }
        return writer;
    }

    private StringBuilder fileArffPhrase(String[] lines, String relationName){
        StringBuilder writer = new StringBuilder();
        try{
            // Creates the attributes of the file arff.
            FastVector vector = null;
            Attribute line = new Attribute("line");
            Attribute text = new Attribute("text", vector);

            // Creating a vector of the attributes.
            FastVector vectorAttributes = new FastVector();
            vectorAttributes.addElement(line);
            vectorAttributes.addElement(text);

            // Creates a new instance to a file .arff
            Instances instances =
                    new Instances(relationName,vectorAttributes, 0);

            // Creates all records for entry to the instance created.
            for(int i = 0; i < lines.length; i++){
                Instance inst = new Instance(2);
                inst.setValue(line, i + 1);
                inst.setValue(text, lines[i].trim());
                instances.add(inst);
            }

            writer.append(instances.toString());
        }catch(Exception e){
            writer = null;
            System.out.println(e.getMessage());
        }
        return writer;
    }

    private StringBuilder fileArffWord(String[] lines, String relationName){
        StringBuilder writer = new StringBuilder();
        try{
            // Creates the attributes of the file arff.
            FastVector vector = null;
            Attribute line = new Attribute("line");
            Attribute text = new Attribute("text", vector);

            // Creating a vector of the attributes.
            FastVector vectorAttributes = new FastVector();
            vectorAttributes.addElement(line);
            vectorAttributes.addElement(text);

            // Creates a new instance to a file .arff
            Instances instances =
                    new Instances(relationName,vectorAttributes, 0);
            // Creates all records for entry to the instance created.
            for(int i = 0; i < lines.length; i++){
                String[] words = lines[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    Instance inst = new Instance(2);
                    inst.setValue(line, i + 1);
                    inst.setValue(text, words[j].trim());
                    instances.add(inst);
                }
            }
            writer.append(instances.toString());
        }catch(Exception e){
            writer = null;
            System.out.println(e.getMessage());
        }
        return writer;
    }

    /**
     * @param lines: receives the lines that will be processed on .ARFF.
     * @param relationName: the name of relation created by file .ARFF.
     * @return a new file processed on .ARFF.
     */
    public StringBuilder fileArffNominal(String[] lines, String relationName){
        StringBuilder writer = new StringBuilder();
        try{
            // Verifier the type of creation.
            // Creates the attributes of the file arff.
            Attribute line = new Attribute("line");
            Attribute text = new Attribute("text", createNominal(lines));

            // Creating a vector of the attributes.
            FastVector vectorAttributes = new FastVector();
            vectorAttributes.addElement(line);
            vectorAttributes.addElement(text);

            // Creates a new instance to a file .arff
            Instances instances =
                    new Instances(relationName,vectorAttributes, 0);
            // Creates all records for entry to the instance created.
            for(int i = 0; i < lines.length; i++){
                String[] words = lines[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    Instance inst = new Instance(2);
                    inst.setValue(line, i + 1);
                    inst.setValue(text, words[j].trim());
                    instances.add(inst);
                }
            }
            writer.append(instances.toString());
        }catch(Exception e){
            System.out.println(e.getMessage());
            writer = null;
        }
        return writer;
    }

    private FastVector createNominal(String[] lines){
        FastVector vector = new FastVector();
        ArrayList<String> list = new ArrayList();

        try{
            for(int i = 0; i < lines.length; i++){
                String[] words = lines[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    if(!list.contains(words[j].trim().toUpperCase()) &&
                            words[j].trim().length() > 0){
                        list.add(words[j].trim().toUpperCase());
                    }
                }
            }

            for(String element: list) vector.addElement(element);
        }catch(Exception e){
            vector = null;
            System.out.println(e.getMessage());
        }
        return vector;
    }

    private FastVector createNominal(String[] lines, String[] lines1){
        FastVector vector = new FastVector();
        ArrayList<String> list = new ArrayList();

        try{
            for(int i = 0; i < lines.length; i++){
                String[] words = lines[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    if(!list.contains(words[j].trim().toUpperCase()) &&
                            words[j].trim().length() > 0){
                        list.add(words[j].trim().toUpperCase());
                    }
                }
            }

            for(int i = 0; i < lines1.length; i++){
                String[] words = lines1[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    if(!list.contains(words[j].trim().toUpperCase()) &&
                            words[j].trim().length() > 0){
                        list.add(words[j].trim().toUpperCase());
                    }
                }
            }

            for(String element: list) vector.addElement(element);
        }catch(Exception e){
            vector = null;
            System.out.println(e.getMessage());
        }
        return vector;
    }

    public Instances fileArffNominalJoin(String[] linComp, String relationName){
        Instances instanceResult;
        try{
            String[] lines = this.fileStemmer.split("\n");
            FastVector typeTexts = new FastVector();
            typeTexts.addElement("current");
            typeTexts.addElement("compared");

            // Verifier the type of creation.
            // Creates the attributes of the file arff.
            Attribute line = new Attribute("line");
            Attribute typeText = new Attribute("typeText", typeTexts);
            Attribute text = new Attribute("text", 
                    createNominal(lines, linComp));

            // Creating a vector of the attributes.
            FastVector vectorAttributes = new FastVector();
            vectorAttributes.addElement(line);
            vectorAttributes.addElement(typeText);
            vectorAttributes.addElement(text);

            // Creates a new instance to a file .arff
            Instances instances =
                    new Instances(relationName,vectorAttributes, 0);
            // Creates all records for entry to the instance created.
            for(int i = 0; i < lines.length; i++){
                String[] words = lines[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    Instance inst = new Instance(3);
                    inst.setValue(line, i + 1);
                    inst.setValue(typeText, "current");
                    inst.setValue(text, words[j].trim());
                    instances.add(inst);
                }
            }

            for(int i = 0; i < linComp.length; i++){
                String[] words = linComp[i].split(" ");
                for(int j = 0; j < words.length; j++){
                    Instance inst = new Instance(3);
                    inst.setValue(line, i + 1);
                    inst.setValue(typeText, "compared");
                    inst.setValue(text, words[j].trim());
                    instances.add(inst);
                }
            }
            instanceResult = instances;
        }catch(Exception e){
            System.out.println(e.getMessage());
            instanceResult = null;
        }
        return instanceResult;
    }

    public String getPercPlagio(Instances instances){
        double percPlagio = 0;
        DecimalFormat format = new DecimalFormat("##,##00.00");
        try{
            percPlagio = 100 - (((instances.numDistinctValues(2) -
            (instances.numInstances() - instances.numDistinctValues(2))) * 100)/
            instances.numInstances());
        }
        catch(Exception e){
            System.out.println(e.getMessage());
            percPlagio = 0;
        }        
        return format.format(percPlagio).replace(',', '.');
    }

}
